package com.example.prom.ok.y2023.work.maxmind;

import com.alibaba.fastjson.JSON;
import com.example.prom.listener.ExcelListener;
import com.example.prom.strategy.excel.CustomCellStyleStrategy;
import com.example.prom.strategy.excel.CustomColumnWidthStrategy;
import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.exception.AddressNotFoundException;
import com.maxmind.geoip2.model.CityResponse;
import com.maxmind.geoip2.record.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
import java.util.stream.Collectors;

import static com.alibaba.excel.EasyExcelFactory.read;
import static com.alibaba.excel.EasyExcelFactory.write;

@Slf4j
public class MaxMindHandler3 {

//    public static void main(String[] args) throws Exception{
//        List<MaxMindIpReaderVO3> MaxMindIpReaderVO3S = readExcel();
//        List<RegionVO2> regionVO2s = readExcel2();
//        log.info("去重前的数据总量：{}", MaxMindIpReaderVO3S.size());
//        // ip去重
//        ArrayList<MaxMindIpReaderVO3> removeDup = MaxMindIpReaderVO3S.stream().collect(Collectors.collectingAndThen(
//                Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(MaxMindIpReaderVO3::getClient_ip))), ArrayList::new));
//        log.info("去重后的数据总量：{}", removeDup.size());
//        List<String> regions = regionVO2s.stream().map(RegionVO2::getRegion).collect(Collectors.toList());
//        //        System.out.println(maxMindIpReaders.size());
//        List<MaxMindIpReaderVO3> notMatchList = new ArrayList<>();
//        for (MaxMindIpReaderVO3 MaxMindIpReaderVO3 : removeDup) {
////            log.info("maxMindIpReader:{}",JSON.toJSONString(MaxMindIpReaderVO3));
//            String client_ip = MaxMindIpReaderVO3.getClient_ip();
//            MaxMindResultDTO maxMindResultDTO = validateIP(client_ip.trim(), notMatchList, MaxMindIpReaderVO3);
//
//            String countryNameEn = maxMindResultDTO.getCountryNameEn();
//            String regionNameEn = maxMindResultDTO.getRegionNameEn();
//            if (!StringUtils.isEmpty(countryNameEn)) {
//                countryNameEn = countryNameEn.toLowerCase();
//            }
//            if (!StringUtils.isEmpty(regionNameEn)) {
//                regionNameEn = regionNameEn.toLowerCase();
//            }
//            if (regions.contains(countryNameEn) || regions.contains(regionNameEn)) {
//                notMatchList.add(MaxMindIpReaderVO3);
//                MaxMindIpReaderVO3.setMatch_result("not match");
//                String reason = "含有ip禁止国("+client_ip+":"+countryNameEn+"/"+regionNameEn+")";
//                MaxMindIpReaderVO3.setReason(reason);
//            }
//            else {
//                MaxMindIpReaderVO3.setMatch_result("match");
//                String reason = client_ip+":"+countryNameEn+"/"+regionNameEn;
//                MaxMindIpReaderVO3.setReason(reason);
//            }
//
//
//        }
//        String writeFileName = "C:\\Users\\hp\\Desktop\\ok\\userIPOrigin.xlsx";
//        writeExcel(removeDup, writeFileName);
//        String writeFileName2 = "C:\\Users\\hp\\Desktop\\ok\\userIPCheckResult.xlsx";
//        writeExcel(notMatchList, writeFileName2);
//    }

    public static void main(String[] args) {
        MaxMindResultDTO maxMindResultDTO = validateIP("103.211.229.179", null, null);
        System.out.println(JSON.toJSONString(maxMindResultDTO));
    }

    public static List<MaxMindIpReaderVO3> readExcel() {
        String fileName = "C:\\Users\\hp\\Desktop\\user_ip_04092023.xlsx";
        ExcelListener<MaxMindIpReaderVO3> excelListener = new ExcelListener<>();
        read(fileName, MaxMindIpReaderVO3.class, excelListener).sheet().doRead();
        List<MaxMindIpReaderVO3> dataList = excelListener.getDataList();
        return dataList;
    }

    public static List<RegionVO2> readExcel2() {
        String fileName = "C:\\Users\\hp\\Desktop\\bannedCountry.xlsx";
        ExcelListener<RegionVO2> excelListener = new ExcelListener<>();
        read(fileName, RegionVO2.class, excelListener).sheet().doRead();
        List<RegionVO2> dataList = excelListener.getDataList();
        return dataList;
    }

    public static void writeExcel(List<MaxMindIpReaderVO3> writerList, String writeFileName){
        write(writeFileName, MaxMindIpReaderVO3.class).sheet().head(MaxMindIpReaderVO3.class)
                .registerWriteHandler(new CustomColumnWidthStrategy())
                .registerWriteHandler(new CustomCellStyleStrategy()).doWrite(writerList);
    }

    public static MaxMindResultDTO validateIP(String ip, List<MaxMindIpReaderVO3> notMatchList, MaxMindIpReaderVO3 vo3) {
        MaxMindResultDTO resultDTO = new MaxMindResultDTO();
        try {
            // A File object pointing to your GeoIP2 or GeoLite2 database
            File database = new File("C:\\Users\\hp\\Desktop\\ok\\work\\GeoIP2-City_20230404\\GeoIP2-City.mmdb");

// This creates the DatabaseReader object. To improve performance, reuse
// the object across lookups. The object is thread-safe.
            DatabaseReader reader = new DatabaseReader.Builder(database).build();

            InetAddress ipAddress = InetAddress.getByName(ip);

// Replace "city" with the appropriate method for your database, e.g.,
// "country".
            CityResponse response = reader.city(ipAddress);

            Country country = response.getCountry();
//        System.out.println(country.getIsoCode());            // 'US'
//        System.out.println(country.getName());               // 'United States'
//        System.out.println(country.getNames().get("zh-CN")); // '美国'

            Subdivision subdivision = response.getMostSpecificSubdivision();
//        System.out.println(subdivision.getName());    // 'Minnesota'
//        System.out.println(subdivision.getNames().get("zh-CN"));    // 'Minnesota'
//        System.out.println(subdivision.getIsoCode()); // 'MN'

            City city = response.getCity();
//        System.out.println(city.getName()); // 'Minneapolis'
//        System.out.println(city.getNames().get("zh-CN")); // 'Minneapolis'

            Postal postal = response.getPostal();
//        System.out.println(postal.getCode()); // '55455'

            Location location = response.getLocation();
//        System.out.println(location.getLatitude());  // 44.9733
//        System.out.println(location.getLongitude()); // -93.2323


            resultDTO.setCountryIsoCode(country.getIsoCode());
            resultDTO.setCountryNameEn(country.getName());
            resultDTO.setCountryNameZh(country.getNames().get("zh-CN"));
            resultDTO.setRegionIsoCode(subdivision.getIsoCode());
            resultDTO.setRegionNameEn(subdivision.getName());
            resultDTO.setRegionNameZh(subdivision.getNames().get("zh-CN"));
            resultDTO.setCityNameEn(city.getName());
            resultDTO.setCityNameZh(city.getNames().get("zh-CN"));
            resultDTO.setLatitude(location.getLatitude());
            resultDTO.setLongitude(location.getLongitude());

        } catch (Exception e){
            log.error("ip解析异常,ip:{}", ip, e);
            if(e instanceof AddressNotFoundException){
                log.info("--------------{},{}", e.getMessage(), ip);
            }
            resultDTO.setRegionNameEn(e.getMessage());
            resultDTO.setRegionNameZh(e.getMessage());
            vo3.setReason(e.getMessage());
            vo3.setMatch_result("not match");
            notMatchList.add(vo3);
        }
        return resultDTO;
    }
}
